package com.tedu.api.io;

import org.junit.Test;

import java.io.*;

public class IOAPI {
/**
 * 标准IO流----目的：数据传输 输出文本、图片
 * java定义一套标准流-->数据传输-->
 * 标注流规则①：方向划分 输入流和输出流
 *
 *         ②：功能划分
 *         低级流【
 * FileOutputStream 构造器使用
 * new FilePutStream("路径+文件全称“boolean)
 * new FilePutStream(路径+文件全称,boolean append)
 * 写出文件的同时实现追加效果，第二个参数：true 追加
 *                                  false 默认不追加
 * new FileOutputStream(File file,boolean append)
 * 写出文件，采用File传入路径+全称
 *
 *
 *
 *
 */


   @Test
   public void testFOS() {
      // RandomAccessFile raf=new RandomAccessFile("fos.txt","rw");
      //低级流-----文件的输出流对象----从程序当中写出来“文件：数据”
      FileOutputStream fos = null;
      try {
         fos = new FileOutputStream("fos.txt");
         //需求：fos.txt  增加一行文本,每次运行实现追加效果
         String say = "李桃桃健健康康的哦";//字符串由字符数组构成---数组的功能---getBytes()转换为字节数组
         //输出流---写功能：write(byte[] b); 写出字节数组
         fos.write(say.getBytes());
         //关闭流--目的：节省内存开销
      } catch (FileNotFoundException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } catch (Exception e) {
         e.printStackTrace();
      } finally {
         if (fos != null)
            try {
               fos.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
      }


   }

   /**
    * 文件输入流：读入操作
    * FileInputStream 文件输入流
    * read() 返回一个读取一个字节--效率低
    * read(字节数组byte[] b)
    * 返回一个”指定字节数组：空间大小“的读取---效率高
    * 需求：读入fos.txt文件内容
    *
    */
   @Test
   public void testFIS() {
      //创建文件输入流---读入：fos.txt
      FileInputStream fis=null;
      byte[]data= new byte[0];
      int len= -1;
      try {
         fis=new FileInputStream("fos.txt");
         //读入效率高：创建字节数组-指定空间数组10KB
         data = new byte[1024*10];
         //读入操作：read(字节数组) |  以10KB读入数据
         len = fis.read(data);
      }catch (FileNotFoundException e){
         e.printStackTrace();
      }catch (IOException e) {
         e.printStackTrace();
      } finally {
         if (fis!=null)
            try {
               fis.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
      }
      //写出：文本-----字符串---针对流操作，提供构造器
      //                     文件按照“指定字节数组的空间”写入程序中
      //                     从0开始写入数据，写入到-1结束
      //                     len:十进制转换为二进制，写入，不等于-1，一直写入
      // 一次性将给定的数据按照字节数组指定的空间大小，写出成字符串
      String str=new String(data,0,len);
      System.out.println("打印Fos.txt文件: "+str);


   }

   /**
    * 需求：利用标准流实现视频复制粘贴
    *
    */
   public void testCV()  {
      //1.从“复制视频.mp4”复制操作---读入
      FileInputStream fis=null;
      //2.创建新文件“新文件.mp4”粘贴操作---写出
      FileOutputStream fos=null;

      try {
         fis=new FileInputStream("新视频.mp4");
         fos=new FileOutputStream("新的视频1.mp4");
         //3.保存每次读取的数据【字节量int】
         int len=-1;
         //4.一直从“复制文件.mp4”进行读入操作，入不等于-1一直读
         //4.1同时 写出“新文件.mp4”
         //len=fis.read()
         while ((len=fis.read())!=-1){//true
            fos.write(len);
         }
      }catch(FileNotFoundException e){
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } finally {
         if (fis!=null)
            //5.关闭流   ----测：效率低--正常播放
            try {
               fis.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         if(fos!=null)
            try {
               fos.close();
            } catch (IOException e) {
               e.printStackTrace();
            }

      }
   }
@Test
   public void testCVS()  {
      //1.创建一个低级流：读入“新视频.MP4”
      FileInputStream fis=null;
      //1.创建一个高级流：套在低级流上【自带缓冲区：字节数组】
      BufferedInputStream bis=null;
      //2.创建低级流，写出"高效的视频.mp4“
      FileOutputStream fos=null;
      //2.创建一个高级流：套在低级流上【自带缓冲区：字节数组】
      BufferedOutputStream bos=null;
      try {
         fis=new FileInputStream("新视频.mp4");
         bis=new BufferedInputStream(fis);
         fos=new FileOutputStream("高效的视频");
         bos=new BufferedOutputStream(fos);
      } catch (FileNotFoundException e) {
         e.printStackTrace();
      } finally {
      }

      //保存数据
      int len=-1;
      //4.高级流---低级流方法一致----read()读取内嵌缓冲区【字节数组】
      //  高级流---低级流方法一致---write()写出内嵌缓冲区【字节数组】
      //一直从“新视频.MP4”读取数据，不等于-1，一直读
      //(len=bis.read())!=-1
      long start= System.currentTimeMillis();//系统时间毫秒数
      try {
         while ((len=bis.read())!=-1){
            bos.write(len);
         }
      } catch (IOException e) {
         e.printStackTrace();
      } finally {
         if (bos!=null)
            try {
               bos.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
      }
      long end=System.currentTimeMillis();
      System.out.println("缓冲流【自带缓冲区】："+(end-start+"毫秒数"));
      //关闭流--高级流与低级流：都关---->高级流间接性关闭低级流--->关闭高级流
      //高级流--缓冲输入流
      //高级流--缓冲输入流

   }
   /**
    * 高级流----缓冲流【内嵌缓冲区】
    * BufferedOutputStream 缓冲输出流
    *
    * 需求：通过缓冲输出流实现从程序写出文件：bos.txt，写出内容
    */
   @Test
   public void testBOS() throws IOException {
      //1.创建低级流-->bos.txt
      FileOutputStream fos=new FileOutputStream("bos.txt");
      //创建高级流-->缓冲区：字节数组--合理【传输效率】
      BufferedOutputStream bos=new BufferedOutputStream(fos);
      //3.写出文本内容
      String str="这辈子在时代峰峻走不出来~";
      //4.写出到bos.txt 文件中：字符串转成字节数组--写出
      bos.write(str.getBytes());
      bos.close();  //关闭流---一定把缓冲区数据全部写出

   }
   /**
    * 标准IO---成对【低级流+高级流】结合异常---数据传输---成功【异常需要辅助
    * 需求：重构 testBOS() 单元测试
    */

   @Test
   public void testBOSIO(){
      //1.置空流---提升所有流的作用域：使用范围
      FileOutputStream fos=null;//低级流：搬运数据
      BufferedOutputStream bos=null;//高级流：缓冲输出流
      //2.捕获流的异常并且作出处理
      try {
         fos=new FileOutputStream("bos.txt");//低级流
         bos=new BufferedOutputStream(fos);//高级流：缓冲区：字节数组
         bos.write("我爱王源".getBytes());
         bos.flush();
      }catch (FileNotFoundException e){//IO流当中“小”异常
         e.printStackTrace();
      }catch (IOException e) {//IO流当中“中”异常：小异常父类
         e.printStackTrace();
      }catch (Exception e){//"大"异常 Exception
         e.printStackTrace();
      }finally {  //一定执行代码块
         //关闭流---高级流--释放资源
         //判断：高级流一定不为空，关闭
         if (bos!=null)

            try {
               bos.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
      }
   }
}

